module Spree
  class CountryToTimezone
    prepend Spree::ServiceModule::Base

    CAPITAL_CITIES = {
      "AD"=>"Andorra la Vella",
     "AE"=>"Abu Dhabi",
     "AF"=>"Kabul",
     "AG"=>"Saint John's",
     "AI"=>"The Valley",
     "AL"=>"Tirana",
     "AM"=>"Yerevan",
     "AN"=>"Willemstad",
     "AO"=>"Luanda",
     "AQ"=>nil,
     "AR"=>"Buenos Aires",
     "AS"=>"Pago Pago",
     "AT"=>"Vienna",
     "AU"=>"Canberra",
     "AW"=>"Oranjestad",
     "AZ"=>"Baku",
     "BA"=>"Sarajevo",
     "BB"=>"Bridgetown",
     "BD"=>"Dhaka",
     "BE"=>"Brussels",
     "BF"=>"Ouagadougou",
     "BG"=>"Sofia",
     "BH"=>"Manama",
     "BI"=>"Bujumbura",
     "BJ"=>"Porto-Novo",
     "BL"=>"Gustavia",
     "BM"=>"Hamilton",
     "BN"=>"Bandar Seri Begawan",
     "BO"=>"La Paz",
     "BR"=>"Brasilia",
     "BS"=>"Nassau",
     "BT"=>"Thimphu",
     "BV"=>nil,
     "BW"=>"Gaborone",
     "BY"=>"Minsk",
     "BZ"=>"Belmopan",
     "CA"=>"Ottawa",
     "CC"=>"West Island",
     "CD"=>"Kinshasa",
     "CF"=>"Bangui",
     "CG"=>"Brazzaville",
     "CH"=>"Bern",
     "CI"=>"Yamoussoukro",
     "CK"=>"Avarua",
     "CL"=>"Santiago",
     "CM"=>"Yaounde",
     "CN"=>"Beijing",
     "CO"=>"Bogota",
     "CR"=>"San Jose",
     "CU"=>"Havana",
     "CV"=>"Praia",
     "CX"=>"The Settlement",
     "CY"=>"Nicosia",
     "CZ"=>"Prague",
     "DE"=>"Berlin",
     "DJ"=>"Djibouti",
     "DK"=>"Copenhagen",
     "DM"=>"Roseau",
     "DO"=>"Santo Domingo",
     "DZ"=>"Algiers",
     "EC"=>"Quito",
     "EE"=>"Tallinn",
     "EG"=>"Cairo",
     "EH"=>nil,
     "ER"=>"Asmara",
     "ES"=>"Madrid",
     "ET"=>"Addis Ababa",
     "FI"=>"Helsinki",
     "FJ"=>"Suva",
     "FK"=>"Stanley",
     "FM"=>"Palikir",
     "FO"=>"Torshavn",
     "FR"=>"Paris",
     "GA"=>"Libreville",
     "GB"=>"London",
     "GD"=>"Saint George's",
     "GE"=>"T'bilisi",
     "GG"=>"Saint Peter Port",
     "GH"=>"Accra",
     "GI"=>"Gibraltar",
     "GL"=>"Nuuk",
     "GM"=>"Banjul",
     "GN"=>"Conakry",
     "GQ"=>"Malabo",
     "GR"=>"Athens",
     "GT"=>"Guatemala City",
     "GU"=>"Hagatna",
     "GW"=>"Bissau",
     "GY"=>"Georgetown",
     "HK"=>"Hong Kong",
     "HM"=>nil,
     "HN"=>"Tegucigalpa",
     "HR"=>"Zagreb",
     "HT"=>"Port-au-Prince",
     "HU"=>"Budapest",
     "ID"=>"Jakarta",
     "IE"=>"Dublin",
     "IL"=>"Jerusalem",
     "IM"=>"Douglas",
     "IN"=>"New Delhi",
     "IO"=>nil,
     "IQ"=>"Baghdad",
     "IR"=>"Tehran",
     "IS"=>"Reykjavik",
     "IT"=>"Rome",
     "JE"=>"Saint Helier",
     "JM"=>"Kingston",
     "JO"=>"Amman",
     "JP"=>"Tokyo",
     "KE"=>"Nairobi",
     "KG"=>"Bishkek",
     "KH"=>"Phnom Penh",
     "KI"=>"Tarawa",
     "KM"=>"Moroni",
     "KN"=>"Basseterre",
     "KP"=>"Pyongyang",
     "KR"=>"Seoul",
     "KW"=>"Kuwait City",
     "KY"=>"George Town",
     "KZ"=>"Astana",
     "LA"=>"Vientiane",
     "LB"=>"Beirut",
     "LC"=>"Castries",
     "LI"=>"Vaduz",
     "LK"=>"Colombo",
     "LR"=>"Monrovia",
     "LS"=>"Maseru",
     "LT"=>"Vilnius",
     "LU"=>"Luxembourg",
     "LV"=>"Riga",
     "LY"=>"Tripoli",
     "MA"=>"Rabat",
     "MC"=>"Monaco",
     "MD"=>"Chisinau",
     "ME"=>"Podgorica",
     "MF"=>"Marigot",
     "MG"=>"Antananarivo",
     "MH"=>"Majuro",
     "MK"=>"Skopje",
     "ML"=>"Bamako",
     "MM"=>"Rangoon",
     "MN"=>"Ulaanbaatar",
     "MO"=>nil,
     "MP"=>"Saipan",
     "MR"=>"Nouakchott",
     "MS"=>"Plymouth",
     "MT"=>"Valletta",
     "MU"=>"Port Louis",
     "MV"=>"Male",
     "MW"=>"Lilongwe",
     "MX"=>"Mexico City",
     "MY"=>"Kuala Lumpur",
     "MZ"=>"Maputo",
     "NA"=>"Windhoek",
     "NC"=>"Noumea",
     "NE"=>"Niamey",
     "NF"=>"Kingston",
     "NG"=>"Abuja",
     "NI"=>"Managua",
     "NL"=>"Amsterdam",
     "NO"=>"Oslo",
     "NP"=>"Kathmandu",
     "NR"=>nil,
     "NU"=>"Alofi",
     "NZ"=>"Wellington",
     "OM"=>"Muscat",
     "PA"=>"Panama City",
     "PE"=>"Lima",
     "PF"=>"Papeete",
     "PG"=>"Port Moresby",
     "PH"=>"Manila",
     "PK"=>"Islamabad",
     "PL"=>"Warsaw",
     "PM"=>"Saint-Pierre",
     "PN"=>"Adamstown",
     "PR"=>"San Juan",
     "PS"=>nil,
     "PT"=>"Lisbon",
     "PW"=>"Melekeok",
     "PY"=>"Asuncion",
     "QA"=>"Doha",
     "RO"=>"Bucharest",
     "RS"=>"Belgrade",
     "RU"=>"Moscow",
     "RW"=>"Kigali",
     "SA"=>"Riyadh",
     "SB"=>"Honiara",
     "SC"=>"Victoria",
     "SD"=>"Khartoum",
     "SE"=>"Stockholm",
     "SG"=>"Singapore",
     "SH"=>"Jamestown",
     "SI"=>"Ljubljana",
     "SJ"=>"Longyearbyen",
     "SK"=>"Bratislava",
     "SL"=>"Freetown",
     "SM"=>"San Marino",
     "SN"=>"Dakar",
     "SO"=>"Mogadishu",
     "SR"=>"Paramaribo",
     "ST"=>"Sao Tome",
     "SV"=>"San Salvador",
     "SY"=>"Damascus",
     "SZ"=>"Mbabane",
     "TC"=>"Grand Turk",
     "TD"=>"N'Djamena",
     "TF"=>nil,
     "TG"=>"Lome",
     "TH"=>"Bangkok",
     "TJ"=>"Dushanbe",
     "TK"=>nil,
     "TL"=>"Dili",
     "TM"=>"Ashgabat",
     "TN"=>"Tunis",
     "TO"=>"Nuku'alofa",
     "TR"=>"Ankara",
     "TT"=>"Port-of-Spain",
     "TV"=>"Funafuti",
     "TW"=>"Taipei",
     "TZ"=>"Dar es Salaam",
     "UA"=>"Kyiv",
     "UG"=>"Kampala",
     "US"=>"Washington, DC",
     "UY"=>"Montevideo",
     "UZ"=>"Tashkent",
     "VA"=>"Vatican City",
     "VC"=>"Kingstown",
     "VE"=>"Caracas",
     "VG"=>"Road Town",
     "VI"=>"Charlotte Amalie",
     "VN"=>"Hanoi",
     "VU"=>"Port-Vila",
     "WF"=>"Mata-Utu",
     "WS"=>"Apia",
     "YE"=>"Sanaa",
     "YT"=>"Mamoudzou",
     "ZA"=>"Pretoria",
     "ZM"=>"Lusaka",
     "ZW"=>"Harare"}.freeze

    def call(code:)
      case code
      when 'US', 'CA'
        success('Central Time (US & Canada)')
      else
        success(from_timezone_helper(code))
      end
    end

    private

    def from_timezone_helper(code)
      timezones = ActiveSupport::TimeZone.country_zones(code)
      return 'Central Time (US & Canada)' if timezones.empty?

      timezones.first.name if timezones.size == 1

      # If there is more than one timezone for the country, then we'll use the capital city
      # to determine the timezone
      # eg GB has London and Edinburgh
      capital_city = CAPITAL_CITIES[code]
      capital_city_time_zone = timezones.find{ |tz| tz.name.match(capital_city) }
      return capital_city_time_zone.name if capital_city_time_zone.present?

      timezones.first.name
    end
  end
end
